レイトレーシング: レイ
https://gyazo.com/d6a55f0f9fce0e5951e00c89dc790283
レイトレーシングが描画範囲とするディスプレイ上の各ピクセルに対してレイを生成する 基本
レイを定義する際、レイの始点 (ray origin) と方向 (ray direction) の定義が必要
透視投影
例えば、右手, +Y upの3D空間において、手前に5mの位置から奥に向かって透視投影する場合 中心が0・縦横比が1のスクリーン座標 p を用いて、以下のように書ける code:glsl
vec3 ro = vec3(0.0, 0.0, 5.0);
vec3 rd = normalize(vec3(p, -1.0));
平行投影
p を使って始点を動かすことによって、平行投影もできるよ code:glsl
vec3 ro = vec3(p, 5.0);
vec3 rd = vec3(0.0, 0.0, -1.0);
魚眼レンズ
他の射影方式については、各ページを参照
code:glsl
const float f = 1.0;
float r = length(p);
float theta = 2.0 * asin(r / f / 2.0);
vec3 rd = vec3(sin(theta) * p / r, -cos(theta));
Field of View
code:glsl
rd = normalize(vec3(p, -1.0));
FOVを使う
視野角 FOV (弧度法) を設定したい場合、以下のようなコードになるよ code:glsl
rd = normalize(vec3(p * tan(FOV / 2.0), -1.0));
sizecoding
code:glsl
rd = normalize(vec3(p, -2.0));
このとき、
$ FOV = 2 \ {\rm atan} \left( - \frac{1}{z} \right)
主なZ値ごとのFOVは以下のようになる
table:fov
z fov
-0.5 126.9 °
-1.0 90.0 °
-1.5 67.4 °
-2.0 53.1 °
-2.5 43.6 °
-3.0 36.9 °
-4.0 28.1 °
-5.0 22.6 °
code:js
.map((z) => {
const rad = 2.0 * Math.atan(-1 / z);
const deg = rad / Math.PI * 180.0;
const degDisplay = deg.toFixed(1);
})
35mm換算だと、-3.0が35mm (37.8°) に結構近いし、-4.0が50mm (27.0°) に結構近い